<?php 

namespace App\Repositories;

use Illuminate\Container\Container as App;
use App\Services\PHPTree;
use Illuminate\Http\Request;
use App\Repositories\CustomerRepository;
use App\Repositories\LanCompleteRepository;
use App\Repositories\OtherOrderRepository;
use Carbon\Carbon;
use Excel;

class OrderRepository extends Repository
{
    public function __construct(App $app, CustomerRepository $customer, DepartmentRepository $department, UserRepository $user) {
        parent::__construct($app); 
        $this->customer = $customer;
        $this->department = $department;
        $this->user = $user;
    }

    public function model() 
    {
        return 'App\Models\Order';
    }    

    public function paginateList($where = [], $page = 20)
    {
        $model = $this->model->with('customer', 'saler', 'designer', 'programmer', 'inputer', 'lan', 'webPermission');
        $where = $where->filter(function ($value) { return $value; });

        $result = $this->filterCondition($model, $where);

        if (!$result) {
            return collect();
        }

        return $model->orderBy('signed_at', 'desc')->orderBy('id', 'desc')->paginate($page);
    }

    // 我的订单
    public function myPaginate($where = [], $page = 20)
    {
       $model = $this->model->with('customer', 'saler', 'designer', 'programmer', 'inputer'); 

        // 当前用户
        $user = auth()->user();
        $userId = $user->id;

        $where->put('closure_user_id', function($query) use ($userId) { 
            $query->where('designer_id', $userId)->orWhere('programmer_id', $userId); 
        });

        return $this->commonPaginate($model, $where, $page);
    }

    // 我的录入
    public function myInputPaginate($where = [], $page = 20)
    {
        $model = $this->model->with('customer');
        $where = $where->filter(function ($value) { return $value; });
        $where->put('inputer_id', auth()->user()->id);

        return $this->commonPaginate($model, $where, $page);
    }

    // 公共分页
    protected function commonPaginate(& $model, $where, $page = 20)
    {
        $result = $this->filterCondition($model, $where);
        if (!$result) {
            return collect();
        }
        return $model->orderBy('signed_at', 'desc')->orderBy('id', 'desc')->paginate($page);
    }

    protected function filterCondition(& $model, $where)
    {
        // 客户名称
        if ($where->has('word')) {
            $word = trim($where->get('word'));
            $cids = $this->customer->findIdsByname($word);

            if (!empty($cids)) {
                $model->where(function ($query) use ($cids, $word) {
                    $query->whereIn('cid', $cids)->orWhere('domain', 'like', "%{$word}%");
                });
            } else {
                $model->where('domain', 'like', "%{$word}%" );
            }
        }

        // 上线时间
        if ($where->has('start') && $where->has('end')) {

            $dateTypeArray = [1=>'signed_at', 2=>'created_at', 3=>'designed_at', 4=>'produced_at', 5=>'finished_at'];
            $dateField = $dateTypeArray[$where->get('date_field')];

            if ($where->get('date_field') == 2) {
                $model->where('progress', '>', 0);
            }

            $start = Carbon::createFromFormat('Y-m-d', $where->get('start'))->startOfDay();
            $end   = Carbon::createFromFormat('Y-m-d', $where->get('end'))->endOfDay();
            $model->whereBetween($dateField, [$start, $end]);
        } elseif ($where->get('month')) {
            $start = Carbon::createFromFormat('Y-m', $where->get('month'))->startOfMonth();
            $end   = Carbon::createFromFormat('Y-m', $where->get('month'))->endOfMonth();   

            $model->whereBetween('finished_at', [$start, $end]); 
        }

        // 设计师
        if ($where->get('designer')) {
            $designer = $where->get('designer');
            $where->put('designer', function($query) use ($designer) {
                $query->where('designer_id', $designer)->orWhere('programmer_id', $designer); 
            });
        }

        // 含有设计师
        if ($where->get('has-designer')) {
            $model->where('designer_id', '!=', 0);
        }

        // 待分配制作员和录入员
        if ($where->get('nodesigner') && $where->get('type') == 1) {
            $userField = [3=>'programmer_id', 4=> 'inputer_id'];
            if ($where->get('progress') == 3 || $where->get('progress') == 4) {
                $model->where($userField[$where->get('progress')], 0)->where('product', 1);
            }
        }

        // 到期订单
        if ($where->has('duetime')) {
            $duetimeDay = $where->get('duetime');

            if ($duetimeDay == '*') {
                $duetime = Carbon::now()->endOfDay()->toDateTimeString();
            } else {
                $duetime = Carbon::now()->addDays($duetimeDay)->endOfDay()->toDateTimeString();
            }
           
            $model->where('status', 3)->where('expired_at', '<=', $duetime)->where('year', '>', 0);
        }

        // 尾款订单
        if ($where->get('tail') == 1) {
            $model->where('tail_amount', '>', 0);
        }

        // 特殊订单
        if ($where->get('special') == 1) {
            $model->where('special_status', '>', 1);
        } elseif ($where->has('progress') || $where->has('status')) {
            $model->where('special_status', 1);
        }

        // 部门和业务员
        foreach (['saler_id','department_id','region_id'] as $value) {
            if ($where->has($value)) {
                $funName = 'search_'.camel_case($value);
                $this->$funName($where->get($value), $model);
                break;
            }
        }

        $where->forget(['word', 'date_field', 'month', 'duetime', 'tail', 'date_type', 'start', 'end', 'export', 'region_id', 'department_id', 
                        'saler_id', 'nodesigner', 'has-designer', 'special']);

        // 其它条件
        if (!$where->isEmpty()) {
           $where->each(function ($item, $key) use ($model) {
                if ($item instanceof \Closure) {
                    $model->where($item);
                } else {
                    $model->where($key, $item);
                }
            });
        }

        return true;
    }

    protected function search_salerId($saler, $model)
    {
        $model->where('saler_id', $saler); 
    }

    protected function search_departmentId($department, $model)
    {
        $uids = $this->user->getUidsByDepartments($department);

        $model->whereIn('saler_id', $uids);
    }

    protected function search_regionId($region, $model)
    {
        $departments = $this->department->findIds($region);

        $this->search_departmentId($departments, $model);
    }


    public function showOrder($id)
    {
        return $this->model->find($id);
    }

    // 语言版本进度处理
    public function lanProgress($lanOld, & $lan)
    {
        foreach ($lan as $key => $value) {
            $time = $lanOld[$key]['time'];
            if (!isset($lanOld[$key]) || $value['progress'] > $lanOld[$key]['progress']) {
                if (isset($lanOld[$key]['time'])) {
                    $time = $time + [$value['progress']=>time()];
                } else {
                    $time = [$value['progress']=>time()];
                }
            }
            $lan[$key]['time'] = $time;
        }
    }

    public function getOrdersByCustomer($cid)
    {
        return $this->model->with('customer')->where('cid', $cid)->get();
    }

    // 获取客户的订单的ID号
    public function getIdsByCustomer($cids)
    {
        if (!is_array($cids)) {
            $cids = (array)$cids;
        }

        return $this->model->whereIn('cid', $cids)->lists('id');
    }

    // 统计订单数量 - 按照进度-STATUS
    public function getCountByStatusLists()
    {
        return $this->model->select(\DB::raw('status, count(*) as count'))->groupBy('status')->lists('count', 'status');
    }

    // 统计网站完成量
    public function getWebCountPeriod($range)
    {
        // 下单
        $create = $this->model->where('progress', '>', 0)->where('type', 1)->whereBetween('created_at', $range)->count();

        // 设计确认
        $design = $this->model->whereBetween('designed_at', $range)->where('product', 1)->count();

        // 程序确认
        $program = $this->model->whereBetween('produced_at', $range)->where('product', 1)->count();

        // PSD确认
        $psd = $this->model->whereBetween('produced_at', $range)->where('product', 2)->count();
        
        // 上线
        $online = $this->model->whereBetween('finished_at', $range)->where('type', 1)->where('status', 3)->count();

        // 总未完成单量
        $allUnFinish = $this->model->where('type', 1)->whereBetween('progress', [1, 5])->count();
        
        return compact('create', 'design', 'program', 'psd', 'online', 'allUnFinish');
    }

    // 网站进度统计明细
    public function getDetailCountPeriod($range)
    {
        $orderOrder = app(OtherOrderRepository::class);

        $users = $this->user->designerSelectStatus();

        if (!$users) return null;

        $data = [];

        foreach ($users as $key => $value) {

            $data[$key]['name'] = $value;

            // 未完成网站数
            $data[$key]['unfinished'] = $this->model->where('type', 1)->where('progress', '<', 6)->where(function($query) use ($key) {
                                            $query->where('designer_id', $key)->orWhere('programmer_id', $key);
                                        })->count();
            // 未完成录入数
            $data[$key]['uninputed'] = $this->model->where('progress', '<', 6)->where('inputer_id', $key)->count();

            // 定制单下单量
            $data[$key]['create']['A1'] = $this->model->where('type', 1)->whereBetween('created_at', $range)->where('designer_id', $key)->where('product', 1)->count();
            $data[$key]['create']['A2'] = $this->model->whereBetween('designed_at', $range)->where('programmer_id', $key)->where('product', 1)->count();
            // 定制单下单量(其他订单)
            $data[$key]['create']['A3'] = $orderOrder->getCountRange('create.design', $key, $range);
            $data[$key]['create']['A4'] = $orderOrder->getCountRange('create.program', $key, $range);

            // 架构站(PSD)下单量
            $data[$key]['create']['B'] = $this->model->whereBetween('created_at', $range)->where('programmer_id', $key)->where('product', 2)->count();
            // 架构站(PSD)下单量(其他订单)
            $data[$key]['create']['B1'] = $orderOrder->getCountRange('create.psd', $key, $range);

            // 设计确认
            $data[$key]['design'] = $this->model->where('type', 1)->whereBetween('designed_at', $range)->where('designer_id', $key)->where('product', 1)->count();
            // 设计确认(其他订单)
            $data[$key]['design_other'] = $orderOrder->getCountRange('design', $key, $range);

            // 程序确认
            $data[$key]['program'] = $this->model->whereBetween('produced_at', $range)->where('programmer_id', $key)->where('product', 1)->count();
            // 程序确认(其他订单)
            $data[$key]['program_other'] = $orderOrder->getCountRange('program', $key, $range);

            // PSD确认
            $data[$key]['psd'] = $this->model->whereBetween('produced_at', $range)->where('programmer_id', $key)->where('product', 2)->count();
            // PSD确认
            $data[$key]['psd_other'] = $orderOrder->getCountRange('psd', $key, $range);

            // 录入完成量
            $data[$key]['inputed'] = $this->model->whereBetween('finished_at', $range)->where('status', 3)->where('inputer_id', $key)->count();
            // 录入完成量(其他订单)
            $data[$key]['inputed_other'] = $orderOrder->getCountRange('inputed', $key, $range);

            // 网站上线
            $data[$key]['online'] = $this->model->where('type', 1)->whereBetween('finished_at', $range)->where('status', 3)->where(function($query) use ($key) {
                                            $query->where('designer_id', $key)->orWhere('programmer_id', $key);
                                        })->count();
            // 网站上线(其他订单)
            $data[$key]['online_other'] = $orderOrder->getCountRange('online', $key, $range);
        }

        return $data;
    }

    // 小组订单完成情况统计
    public function getTeamCount($range)
    {
        $team = config('system.team');

        $user = $this->user->getUsersByTeam();

        $data = [];
        foreach ($team as $key=>$value) {
            $userIds = $user->get($key) ? explode(',', $user->get($key)) : [];

            if (empty($userIds)) {
                $data[$key]['order'][1] = 0;
                $data[$key]['order'][2] = 0;
                $data[$key]['online'] = 0;
                $data[$key]['unfinish'][1] = 0;
                $data[$key]['unfinish'][2] = 0;
                continue;
            }

            // 定制单下单
            $data[$key]['order'][1] = $this->model->whereBetween('created_at', $range)
                                                  ->whereIn('designer_id', $userIds)->where('product', 1)->count();
            // 架构站下单
            $data[$key]['order'][2] = $this->model->whereBetween('created_at', $range)
                                                  ->whereIn('programmer_id', $userIds)->where('product', 2)->count();
            // 完成量
            $data[$key]['online'] = $this->model->whereBetween('finished_at', $range)
                                                ->whereIn('inputer_id', $userIds)->where('status', 3)->count(); 

            // 剩余单量[1-定制单]                 
            $data[$key]['unfinish'][1] = $this->model->whereIn('designer_id', $userIds)
                                                     ->where('product', 1)->where('status', '<', 3)->count();
            $data[$key]['unfinish'][2] = $this->model->whereIn('programmer_id', $userIds)
                                                     ->where('product', 2)->where('status', '<', 3)->count();                                                       
        }

        return $data;
    }

    // 统计订单数量 - 按照条件
    public function getCountListsWhere($where, $groupField='designer_id')
    {
        $model = $this->model;

        foreach ($where as $field => $value) {
            if (is_array($value)) {
                if (count($value) === 3) {
                    list($field, $operator, $search) = $value;
                    $model = $model->where($field, $operator, $search);
                } elseif (count($value) === 2) {
                    list($field, $search) = $value;
                    $model = $model->where($field, '=', $search);
                }
            } else {
                $model = $model->where($field, '=', $value);
            }
        }

        return $model->select(\DB::raw("{$groupField}, count(*) as count"))->where($groupField, '>', 0)
                     ->groupBy($groupField)->lists('count', $groupField);
    }

    public function getCountWhere($where)
    {
        $model = $this->model;

        foreach ($where as $field => $value) {
            if (is_array($value)) {
                if (count($value) === 3) {
                    list($field, $operator, $search) = $value;
                    $model = $model->where($field, $operator, $search);
                } elseif (count($value) === 2) {
                    list($field, $search) = $value;
                    $model = $model->where($field, '=', $search);
                }
            } else {
                $model = $model->where($field, '=', $value);
            }
        }

        return $model->count();
    }

    /**
     * 批量更新订单所属的业务员
     *
     * @param  int|array $ids 客户信息ID
     * @param  int  $saler  业务员ID
     * @return Response
     */
    // 
    public function updateSaler($cid, $salerId)
    {
        $cid = (array)$cid;

        return $this->model->whereIn('cid', $cid)->update(['saler_id'=>$salerId]);
    }

    // 统计网站类订单每个进度的数量
    public function progressCounts($type=1)
    {
        $groups = [1=>'progress', 2=>'status'];

        return $this->model->where('type', $type)->where('special_status', 1)->select($groups[$type], \DB::raw('count(*) as count'))
                           ->groupBy($groups[$type])->lists('count', $groups[$type]);
    }

    public function specialCounts($type=1)
    {
        return $this->model->where('type', $type)->where('special_status', '>', 1)->count();
    }

    // 统计网站类订单每个进度的数量 - 我的订单
    public function myProgressCounts($type=1, $userId)
    {
        $groups = [1=>'progress', 2=>'status'];

        return $this->model->where('type', $type)->where(function ($query) use ($userId) {
                    $query->where('designer_id', $userId)->orWhere('programmer_id', $userId);
                })->select($groups[$type], \DB::raw('count(*) as count'))->groupBy($groups[$type])->lists('count', $groups[$type]);
    }

    // 我的录入进度数量统计
    public function myInputProgressCounts($userId)
    {
        return $this->model->where('inputer_id', $userId)->select('progress', \DB::raw('count(*) as count'))
                           ->groupBy('progress')->lists('count', 'progress');
    }

    // 导出订单列表(Excel)-manaer
    public function exportManagerExcel($where = [])
    {
        $model = $this->model->with('customer');

        $where = $where->filter(function ($item) { return $item; });

        $result = $this->filterCondition($model, $where);

        $temp = $model->get();
        $data = [];
        $data = array (
            ['序号', '提单时间', '到期时间', '上线时间', '客户名称', '年限', '订单类型', '产品明细', '业务员',
            '联系人', '电话', '域名', '签单金额', '到账', '尾款', '当前进度', '备注']
        );

        if (!$temp->isEmpty()) {
            foreach ($temp as $key => $value) {
                $saler = isset($value->saler->name) ? $value->saler->name : '';
                $data[] = [
                   $key+1,
                   $value->signed_at->format('Y-m-d'),
                   $value->expired_at->format('Y-m-d'),
                   $value->finished_at->toDateString() > 0 ? $value->finished_at->format('Y-m-d') : '',
                   $value->customer->name,
                   $value->year,
                   config('system')['product'][$value->type][$value->product],
                   $value->product_detail,
                   $saler,
                   $value->contact_people,
                   $value->phone,
                   $value->domain,
                   (int)$value->amount,
                   ($value->amount - $value->tail_amount),
                   (int)$value->tail_amount,
                   config('system')['order_status'][$value->status],
                   $value->remark
                ];
            }
        }

        return Excel::create('订单列表', function($excel) use ($data) {
            $excel->sheet('导出订单', function($sheet) use ($data) {
                $count = count($data);
                // $sheet->setFontFamily('微软雅黑');
                $sheet->setFontSize(11);
                $sheet->setWidth([     
                    'B' => 12,
                    'C' => 12,
                    'D' => 40,
                    'J' => 15,
                    'K' => 30
                ]);
                $sheet->cells("C2:C{$count}", function($cells) {
                    $cells->setFontColor('#ff0000');
                });

                $sheet->cells("D2:D{$count}", function($cells) {
                    $cells->setFontColor('#009900');
                });

                $sheet->setVerticalCentered(true);
                $sheet->setHorizontalCentered(true);
                $sheet->setBorder('A1:P'.$count, 'thin');
                $sheet->fromArray($data, null, 'A1', false, false);
                $sheet->row(1, function($row) {
                    $row->setBackground('#21d17c');
                    $row->setFontWeight('bold');
                });
            });
            $excel->setTitle('Our new awesome title');
        })->export('xlsx');
    }

    // 导出订单列表(Excel)
    public function exportExcel($where = [])
    {
        $model = $this->model->with('customer');

        $where = $where->filter(function ($item) { return $item; });

        $result = $this->filterCondition($model, $where);

        $temp = $model->get();
        $data = [];
        $data = array (
            ['序号', '提单时间', '上线时间', '客户名称', '域名', '订单类型', '设计师', '总金额', '备注']
        );

        if (!$temp->isEmpty()) {
            foreach ($temp as $key => $value) {
                $data[] = [
                   $key + 1,
                   $value->created_at->format('Y-m-d'),
                   $value->status < 3 ? '' : $value->finished_at->format('Y-m-d'),
                   $value->customer->name,
                   $value->domain,
                   config('system')['product'][$value->type][$value->product],
                   isset($value->designer->name) ? $value->designer->name : '',
                   $value->real_amount,
                   $value->remark
                ];
            }
        }

        return Excel::create('订单列表', function($excel) use ($data) {
            $excel->sheet('导出订单', function($sheet) use ($data) {
                $count = count($data);
                // $sheet->setFontFamily('微软雅黑');
                $sheet->setFontSize(11);
                $sheet->setWidth([     
                    'B' => 12,
                    'C' => 12,
                    'D' => 40,
                    'E' => 30
                ]);
                $sheet->cells("C2:C{$count}", function($cells) {
                    $cells->setFontColor('#009900');
                });

                $sheet->setVerticalCentered(true);
                $sheet->setHorizontalCentered(true);
                $sheet->setBorder('A1:I'.$count, 'thin');
                $sheet->fromArray($data, null, 'A1', false, false);
                $sheet->row(1, function($row) {
                    $row->setBackground('#00b0f0');
                    $row->setFontWeight('bold');
                });
            });
            $excel->setTitle('Our new awesome title');
        })->export('xlsx');
    }

    public function import($file)
    {
        $orders = [];
        $customers = [];
        $data = Excel::load(realpath($file), function($reader) {})->get();

        if (!empty($data) && $data->count()) {
            $system = config('system');

            $lanComplete = app(LanCompleteRepository::class);

            foreach ($data as $key => $value) {
                $city = ['province'=>$value->province, 'city'=>$value->city, 'district'=>$value->district];
                $type     = array_search($value->type, $system['type']);
                $product  = array_search($value->product, $system['product'][$type]);
                $icp      = array_search($value->icp_status, $system['icp_status']);
                $status   = array_search($value->status, $system['order_status']);
                $progress = array_search($value->progress, $system['progress']);
                $package  = array_search($value->web_package, $system['web_package']);

                $languages = explode('-', $value->languages);

                $customer = $this->customer->findBy('name', $value->customer);

                if (!$customer) {
                    // 客户信息
                    $customers = [
                        'name'           => $value->customer,
                        'contact_people' => $value->contact_people,
                        'phone'          => $value->phone,
                        'email'          => $value->email,
                        'domain'         => $value->domain,
                        'city'           => $city,
                        'detail_address' => $value->detail_address,
                    ];
                    $customer = $this->customer->create($customers);
                }

                // 订单信息
                $orders = [
                    'sn'                => makeOrderNumber(),
                    'cid'               => $customer->id,
                    'domain'            => $value->domain,
                    'keywords'          => $value->keywords,
                    'contact_people'    => $value->contact_people,
                    'phone'             => $value->phone,
                    'city'              => $city,
                    'detail_address'    => $value->detail_address,
                    'email'             => $value->email,
                    'type'              => $type,
                    'product'           => $product,
                    'web_package'       => $package,
                    'year'              => intval($value->year),
                    'icp_status'        => $icp,
                    'product_detail'    => $value->product_detail ?: '',
                    'status'            => $status,
                    'progress'          => $progress,
                    'amount'            => intval($value->amount),
                    'real_amount'       => intval($value->real_amount),
                    'tail_amount'       => intval($value->tail_amount),
                    'temp_url'          => $value->temp_url,
                    'signed_at'         => $value->signed_at,
                    'actualed_at'       => $value->actualed_at,
                    'produced_at'       => $value->produced_at,
                    'finished_at'       => $value->finished_at,
                    'remark'            => $value->remark ?: '',
                ];

                $result = $this->create($orders);

                if ($result) {
                    // 添加语言版本
                    if (!empty($languages)) {
                        $languagesFlip = array_flip($system['language']);

                        foreach ($languages as $value) {
                            if (isset($languagesFlip[$value])) {
                                $lans[] = $languagesFlip[$value];
                            }
                        }

                        $lanComplete->multiCreate($result->id, $lans);
                    }
                } 
            }
        }

        return '到处成功，共导入 '.$data->count().' 条订单信息';
    }

    // 判断设计师是否有负责的订单
    public function getCountsByDesigner($id)
    {
        $this->model->where('designer_id', $id)->orWhere('programmer_id', $id)->orWhere('inputer_id', $id)->count();
    }

    // 根据语言完成进度更新对应的时间
    public function updateDate(\App\Models\LanComplete $lan)
    {   
        $order = $this->find($lan->order_id);

        $fills = [];

        if ($lan->progress == 5) {
            // 语言版本
            $lanComplete = app(LanCompleteRepository::class);
            $lans = $lanComplete->findAllBy('order_id', $lan->order_id);

            $progress = $lans->count() == 1 ? 7 : 6;

            if ($order->progress != $progress) {
                $fills['progress'] = $progress;
            }
            if ($order->status != 3) {
               $fills['status'] = 3;
            }
            if ($order->finished_at->toDateTimeString() < 0) {
                $fills['finished_at'] = Carbon::now();
            }
        } elseif ($lan->progress == 2) {
            if ($order->designed_at->toDateTimeString() < 0) {
                $fills['designed_at'] = Carbon::now();
            }
        } elseif ($lan->progress == 3) {
            if ($order->produced_at->toDateTimeString() < 0) {
                $fills['produced_at'] = Carbon::now();
            }
        }

        if (!isset($fills['progress'])) {
            $fills['progress'] = $lan->progress + 1;
        }

        if (!empty($fills)) {
            $order->fill($fills)->save();
        }
    }

    // 修复订单状态
    public function repair()
    {
        // 修正下单时间：
        // 1.等待下单,下单时间-2010.1.1，
        // 2.其他订单中ABC用户全无,下单时间-2010.1.1，
        // 3.下单时间 > 上线时间的，下单时间设定-2010.1.1
        return $this->model->where('type', 1)->where('progress', '-1')->orWhere(function($query) {
             $query->where('designer_id', 0)
                   ->where('programmer_id', 0)
                   ->where('inputer_id', 0);
        })->update(['created_at'=>Carbon::create(2010, 1, 1, 0, 0, 0)]);
    }

        // return $this->model->where('type', 1)->where('progress', '-1')->orWhere(function($query) {
        //     $query->where('status', 3)
        //           ->where('finished_at', '>', '0000-00-00 00:00:00')
        //           ->where('finished_at', '<=', 'created_at');
        // })->orWhere(function($query) {
        //      $query->where('designer_id', 0)
        //            ->where('programmer_id', 0)
        //            ->where('inputer_id', 0);
        // })->update(['created_at'=>Carbon::create(2010, 1, 1, 0, 0, 0)]);


}